import Vue from 'vue';

class WebSocketService {
  constructor() {
    this.ws = null;
    this.isConnected = false;
    this.eventBus = new Vue();
    this.reconnectTimer = null;
    this.reconnectAttempts = 0;
    this.maxReconnectAttempts = 10; // 最大重连次数
    this.reconnectInterval = 3000; // 初始重连间隔3秒
    this.heartbeatTimer = null;
    this.heartbeatInterval = 15000; // 15秒检查一次连接状态
    this.token = null;
    this.autoReconnect = true;

    // 绑定方法到实例，确保this上下文正确
    this.handleMessage = this.handleMessage.bind(this);
    this.handleOpen = this.handleOpen.bind(this);
    this.handleClose = this.handleClose.bind(this);
    this.handleError = this.handleError.bind(this);
  }

  static getInstance() {
    if (!WebSocketService.instance) {
      WebSocketService.instance = new WebSocketService();
    }
    return WebSocketService.instance;
  }

  checkConnection() {
    if (!this.isConnected && this.token) {
      console.log('检测到连接断开，尝试自动恢复');
      this.init(this.token);
    }
  }

  parseMessage(data) {
    try {
      const eventStr = typeof data === 'string' ? data : JSON.stringify(data);
      const fixedData = eventStr
        .replace(/([{,]\s*)(\d+)(\s*:)/g, '$1"$2"$3')
        .replace(/,\s*([}\]])/g, '$1');
      return JSON.parse(fixedData);
    } catch (err) {
      console.error('解析消息失败:', err);
      return null;
    }
  }

  // 初始化连接
  init(token, silent = false) {
    if (!token) {
      console.error('未提供有效的token，无法初始化WebSocket连接');
      return;
    }

    this.token = token;

    if (!silent && this.isConnected) {
      console.log('WebSocket已连接，无需重复初始化');
      return;
    }

    // 关闭现有连接
    if (this.ws && this.ws.readyState !== WebSocket.CLOSED) {
      this.ws.onopen = null;
      this.ws.onmessage = null;
      this.ws.onclose = null;
      this.ws.onerror = null;
      this.ws.close();
    }

    const wsUrl = `ws://120.26.233.80:8084/message/manager?token=${encodeURIComponent(token)}`;
    console.log('正在连接WebSocket:', wsUrl);

    this.ws = new WebSocket(wsUrl);

    // 使用绑定好的处理函数，确保this上下文正确
    this.ws.onopen = this.handleOpen;
    this.ws.onmessage = this.handleMessage;
    this.ws.onclose = this.handleClose;
    this.ws.onerror = this.handleError;
  }

  // 消息处理函数
  handleMessage(event) {
    // 确保this指向当前实例
    if (!this || !(this instanceof WebSocketService)) {
      console.error('消息处理函数中this上下文错误');
      return;
    }

    // console.log('收到原始消息:', event.data.substring(0, 200) + (event.data.length > 200 ? '...' : ''));

    try {
      // 尝试解析JSON
      const data = JSON.parse(event.data);
      // 转发普通消息
      this.eventBus.$emit('ws-message', data);
    } catch (e) {
      // 处理纯文本心跳响应
      if (event.data === 'pong') {
        console.log('收到心跳响应');
        return;
      }

      // 尝试修复格式不正确的JSON
      try {
        const fixedData = this.fixMalformedJSON(event.data);
        this.eventBus.$emit('ws-message', fixedData);
      } catch (fixError) {
        console.error('无法解析消息:', event.data.substring(0, 100), fixError);
      }
    }
  }

  // 连接打开处理函数
  handleOpen() {
    this.isConnected = true;
    this.reconnectAttempts = 0; // 重置重连次数
    this.eventBus.$emit('ws-open');
    console.log('WebSocket已连接');
    this.startHeartbeat(); // 启动心跳检测
  }

  // 连接关闭处理函数
  handleClose(event) {
    this.isConnected = false;
    this.eventBus.$emit('ws-close', event);
    console.log(`WebSocket断开：代码=${event.code}, 原因=${event.reason}`);

    this.stopHeartbeat(); // 停止心跳检测

    // 特殊代码无需重连
    const noReconnectCodes = [1000, 4001];
    if (noReconnectCodes.includes(event.code)) {
      console.log(`无需重连（代码：${event.code}）`);
      if (this.reconnectTimer) clearTimeout(this.reconnectTimer);
      return;
    }

    // 触发重连
    if (this.autoReconnect) {
      this.setupReconnect();
    }
  }

  // 错误处理函数
  handleError(error) {
    this.eventBus.$emit('ws-error', error);
    console.error('WebSocket错误:', error);
    this.stopHeartbeat();
  }

  // 修复格式不正确的JSON（处理常见问题）
  fixMalformedJSON(jsonStr) {
    // 修复缺少引号的属性名
    let fixedStr = jsonStr
      .replace(/([{,]\s*)(\w+)(\s*:)/g, '$1"$2"$3')
      // 修复单引号为双引号
      .replace(/'([^']+)'/g, '"$1"');

    return JSON.parse(fixedStr);
  }

  // 发送消息
  send(message) {
    return new Promise((resolve, reject) => {
      // 检查实例状态
      if (!this || !(this instanceof WebSocketService)) {
        reject(new Error('WebSocketService实例错误'));
        return;
      }

      if (!this.isConnected || !this.ws || this.ws.readyState !== WebSocket.OPEN) {
        console.warn('WebSocket未连接，消息发送失败');
        this.setupReconnect();
        reject(new Error('WebSocket未连接，消息发送失败'));
        return;
      }

      try {
        // 确保消息是有效的JSON格式
        const safeMessage = typeof message === 'string'
          ? message
          : JSON.stringify(message);

        // 检查消息长度是否超出限制
        if (safeMessage.length > 100000) { // 100KB限制，可根据服务器调整
          console.error('消息长度超出限制:', safeMessage.length);
          reject(new Error('消息长度超出限制'));
          return;
        }

        this.ws.send(safeMessage);
        console.log('发送消息:', safeMessage.substring(0, 200) + (safeMessage.length > 200 ? '...' : ''));
        resolve();
      } catch (error) {
        console.error('消息格式错误，无法发送:', error);
        this.eventBus.$emit('ws-send-error', error);
        reject(error);
      }
    });
  }

  // 监听事件
  on(event, callback) {
    this.eventBus.$on(event, callback);
  }

  // 移除事件监听
  off(event, callback) {
    this.eventBus.$off(event, callback);
  }

  // 主动关闭连接（登录退出时调用）
  close() {
    console.log('主动关闭WebSocket连接');
    this.autoReconnect = false; // 关闭后不自动重连
    this.stopHeartbeat();
    if (this.reconnectTimer) clearTimeout(this.reconnectTimer);
    if (this.ws) {
      this.ws.onclose = null; // 避免触发重连
      this.ws.close(1000, 'User Initiated Close'); // 正常关闭代码
      this.isConnected = false;
    }
    
  }

  // 指数退避重连
  setupReconnect() {
    if (this.reconnectTimer) clearTimeout(this.reconnectTimer);

    // 计算重连间隔（指数退避）
    const maxInterval = 30000; // 最大30秒
    let currentInterval = this.reconnectInterval * (this.reconnectAttempts + 1);
    currentInterval = Math.min(currentInterval, maxInterval);

    console.log(`计划 ${currentInterval}ms 后尝试重连（第 ${this.reconnectAttempts + 1} 次）`);

    this.reconnectTimer = setTimeout(() => {
      if (this.isConnected) return;
      if (!this.token) {
        console.error('token不存在，停止重连');
        return;
      }
      // 执行重连
      this.reconnectAttempts++;
      if (this.reconnectAttempts <= this.maxReconnectAttempts) {
        this.init(this.token, true); // 静默重连
      } else {
        console.error(`已达到最大重连次数(${this.maxReconnectAttempts})，停止重连`);
      }
    }, currentInterval);
  }

  // 启动心跳检测
  startHeartbeat() {
    this.stopHeartbeat(); // 清除旧定时器

    this.heartbeatTimer = setInterval(() => {
      // 检查实例状态和连接状态
      if (!this || !(this instanceof WebSocketService) || !this.ws) {
        return;
      }

      // 检查连接状态
      if (this.ws.readyState !== WebSocket.OPEN) {
        console.warn(`WebSocket连接状态异常: ${this.ws.readyState}`);
        this.handleClose({ code: 4408, reason: 'Heartbeat Check Failed' });
        return;
      }

      console.log('WebSocket连接正常');
    }, this.heartbeatInterval);
  }

  // 停止心跳检测
  stopHeartbeat() {
    if (this.heartbeatTimer) {
      clearInterval(this.heartbeatTimer);
      this.heartbeatTimer = null;
    }
  }

  // 页面加载时尝试重连
  tryReconnectOnLoad() {
    const savedToken = localStorage.getItem('managerToken');
    if (savedToken && !this.isConnected) {
      console.log('页面加载，尝试重连WebSocket');
      this.init(savedToken);
    }
  }
}

const instance = WebSocketService.getInstance();
// 页面加载时尝试重连
window.addEventListener('load', () => {
  instance.tryReconnectOnLoad();
});

export default instance;